package com.bite.friend.Service.ServiceImpl;

import Constants.RedisConstant;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bite.friend.DTO.QuestionListDTO;
import com.bite.friend.ES.QuestionES;
import com.bite.friend.ElasticSearch.QuestionRepository;
import com.bite.friend.Mapper.QuestionMapper;
import com.bite.friend.Service.QuestionService;
import com.bite.friend.VO.QuestionDetailVO;
import com.bite.friend.VO.QuestionListVO;
import com.bite.friend.doamin.Question;
import domain.R;
import domain.TableDataInfo;
import enums.ResultCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class QuestionServiceImpl implements QuestionService {

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private QuestionRepository questionRepository;
    
    @Autowired
    private StringRedisTemplate redis;
    @Override
    public TableDataInfo list(QuestionListDTO questionListDTO) {
        long count = questionRepository.count();
        if (count <= 0){
            //需要从数据库中获取数据，且将数据刷新到es中
            refreshEs();
        }

        String keyword = questionListDTO.getKeyword();
        Integer difficulty = questionListDTO.getDifficulty();
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        PageRequest pageRequest = PageRequest.of(questionListDTO.getPage() - 1, questionListDTO.getPageSize(), sort);
        Page<QuestionES> questionES;
        if (StrUtil.isEmpty(keyword) && difficulty == null){
            questionES = questionRepository.findAll(pageRequest);
        } else if (difficulty == null) {
            questionES = questionRepository.findByTitleOrContent(keyword, keyword, pageRequest);
        } else if (StrUtil.isEmpty(keyword)) {
            questionES = questionRepository.findQuestionByDifficulty(difficulty, pageRequest);
        }else {
            questionES = questionRepository.findByTitleOrContentAndDifficulty(keyword, keyword, difficulty, pageRequest);
        }

        if (questionES == null || questionES.getTotalElements() <= 0){
            return TableDataInfo.empty();
        }
        List<QuestionListVO> questionListVOList = BeanUtil.copyToList(questionES.getContent(), QuestionListVO.class);

        return TableDataInfo.success(questionListVOList, questionES.getTotalElements());
    }

    @Override
    public R<QuestionDetailVO> questionDetail(Long questionId) {
        //根据id从es中查询数据
        QuestionES questionES = questionRepository.findById(questionId).orElse(null);
        if (questionES != null){
            QuestionDetailVO questionDetailVO = BeanUtil.copyProperties(questionES, QuestionDetailVO.class);
            return R.success(questionDetailVO);
        }
        Question question = questionMapper.selectById(questionId);
        QuestionDetailVO questionDetailVO = BeanUtil.copyProperties(question, QuestionDetailVO.class);

        //开始线程刷新es
        new Thread(this::refreshEs).start();

        return R.success(questionDetailVO);
    }

    @Override
    public R<String> preQuestion(Long questionId) {
        Long size = redis.opsForList().size(RedisConstant.QUESTION_LIST_ID);
        if (size == null || size == 0){
            //刷新数据
            refreshRedisList();
        }
        //根据题目id来redis中查询该当前index
        long index = redis.opsForList().indexOf(RedisConstant.QUESTION_LIST_ID, questionId.toString());
        if (index == 0){
            throw new RuntimeException("当前题目已经到顶了!");
        }
        long preIndex = index - 1;
        String pre = redis.opsForList().index(RedisConstant.QUESTION_LIST_ID, preIndex);
        return R.success(pre);
    }

    @Override
    public R<String> nextQuestion(Long questionId) {
        Long size = redis.opsForList().size(RedisConstant.QUESTION_LIST_ID);
        if (size == null || size == 0){
            //刷新数据
            refreshRedisList();
        }
        long index = redis.opsForList().indexOf(RedisConstant.QUESTION_LIST_ID, questionId.toString());
        if (index == size - 1){
            throw new RuntimeException("当前题目已经到底了!");
        }
        String nexIndex = redis.opsForList().index(RedisConstant.QUESTION_LIST_ID, index + 1);
        return R.success(nexIndex);
    }

    private void refreshRedisList() {
        List<Question> questions = questionMapper.selectList(new LambdaQueryWrapper<Question>()
                .select(Question::getQuestionId)
                .orderByDesc(Question::getCreateTime));
        if (questions == null || questions.size() == 0){
            throw new RuntimeException("资源不存在，请联系管理员");
        }
        List<String> questionIdList = questions.stream().map(question -> question.getQuestionId().toString()).toList();
        redis.opsForList().rightPushAll(RedisConstant.QUESTION_LIST_ID, questionIdList);
    }

    private void refreshEs() {
        //将question所以数据查询出来
        List<Question> questionList = questionMapper.selectList(new LambdaQueryWrapper<>());
        if (questionList == null || questionList.size() == 0){
            return;
        }
        List<QuestionES> questionES = BeanUtil.copyToList(questionList, QuestionES.class);
        questionRepository.saveAll(questionES);
    }
}
